package de.koller.aframe.util.noise;

import de.koller.aframe.util.misc.ARangeD;
import de.koller.aframe.util.misc.BufferedRandomFloat;
import de.koller.aframe.util.misc.ColorGradient;
import de.koller.aframe.util.noise.n2D.ScrollingPerlin2D;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;

public class PerlinLayer {

	private final BufferedRandomFloat bfr;
	private final ScrollingPerlin2D perlin;
	private final List<ColorRange> colorranges = new ArrayList<>();
	
	public PerlinLayer( String tmpName, Random rnd, int steps, float persistence  ) {
		bfr = new BufferedRandomFloat( "./temp/layer/" + tmpName, rnd );
		perlin = new ScrollingPerlin2D( bfr, steps, persistence, true );
	}
	
	public void addColorRange( double minV, double maxV, int minColo, int maxColor ) {
		colorranges.add( new ColorRange( new ARangeD( minV, maxV ), minColo, maxColor ) );
	}
	
	public float getValue( float x, float y ) {
		return perlin.getValue( x, y );
	}
	
	public int getColorAt( float x, float y ) { 
		for( ColorRange r : colorranges ) {
			float v = this.getValue( x, y );
			if( r.range.isIn( v ) )
				return ColorGradient.cubic( (float)r.range.getScaled( v ), r.mincolor, r.maxcolor );
		}
		return 0x00000000;
	}
	
	public float getScaledValue( float x, float y, float scaledX, float scaledY ) {
		return getValue( 1f / scaledX * x, 1f / scaledY * y );
	}
	
	public int getColorScaledAt( float x, float y, float scaledX, float scaledY ) {
		return getColorAt( 1f / scaledX * x, 1f / scaledY * y );
	}
	
	private static class ColorRange {
		private final ARangeD range;
		private final int mincolor, maxcolor;

		public ColorRange( ARangeD range, int mincolor, int maxcolor ) {
			this.range = range;
			this.mincolor = mincolor;
			this.maxcolor = maxcolor;
		}
	}
}
